package com.sky.seekbar;

import android.animation.AnimatorSet;
import android.animation.ValueAnimator;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Rect;
import android.support.annotation.Nullable;
import android.util.AttributeSet;
import android.view.View;
import android.view.animation.AccelerateDecelerateInterpolator;


/**
 * 相反方向的SeekBar
 * Created by liujian on 2017/11/30.
 */

public class CustormSeekBar extends View
{
    /**
     * 标签偏移量
     */
    private float labelOffsets;
    /**
     * 左边seekBar值
     */
    private SeekBarData leftSeekBarData;
    /**
     * 右边seekBar值
     */
    private SeekBarData rightSeekBarData;
    private int seekBarBgColor = Color.GRAY;//seekBar背景颜色，默认灰色
    private int bgColor = Color.WHITE;//整体view背景颜色
    private int defaultSeekBarBgTextColor = Color.BLACK;//默认seekBar背景上的文字颜色
    /**
     * 文本画笔
     */
    private Paint mPaint;
    /**
     * seekBar画笔
     */
    private Paint seekBarPaint;
    /**
     * 宽
     */
    private int width;
    /**
     * 高
     */
    private int height;
    /**
     * seekBar的高度
     */
    private int seekBarHeight;
    /**
     * seekBar的宽度
     */
    private int seekBarWidth;
    /**
     * 偏移量
     */
    private float offsets;
    /**
     * 进度值偏移量
     */
    private float valueOffsets;
    /**
     * 数值字体大小
     */
    private int valueTextSize;
    /**
     * 标签字体大小
     */
    private int labelTextSize;
    private Rect mBound;
    /**
     * 左侧进度
     */
    private float leftProgress = 0;
    /**
     * 右侧进度
     */
    private float rightProgress = 0;
    /**
     * 左侧seekBar进度条颜色
     */
    private int leftSeekBarColor = Color.BLUE;
    /**
     * 右侧seekBar进度条颜色
     */
    private int rightSeekBarColor = Color.GREEN;
    /**
     * 左侧当前进度
     */
    private float currentLeftPro;
    /**
     * 右侧当前进度
     */
    private float currentRightPro;
    /**
     * 没有进度时显示的文本
     */
    private String emptyText = "暂无数据";
    private long durationMillis = 1500;//执行动画时间，默认一秒
    public CustormSeekBar(Context context)
    {
        super(context);
        initView(context,null);
    }

    public CustormSeekBar(Context context, @Nullable AttributeSet attrs)
    {
        super(context, attrs);
        initView(context,attrs);
    }

    public CustormSeekBar(Context context, @Nullable AttributeSet attrs, int defStyleAttr)
    {
        super(context, attrs, defStyleAttr);
        initView(context,attrs);
    }

    /**
     * 初始化组件view
     * @param context
     * @param attrs
     */
    private void initView(Context context, AttributeSet attrs)
    {
        width = DisplayUtil.getScreenWidth(context);//默认为屏幕宽度
        height = DisplayUtil.dip2px(context,50);//默认高度为50dip
        offsets = DisplayUtil.dip2px(context,6);//默认偏移量为6dip
        valueOffsets = DisplayUtil.dip2px(context,5);//默认进度值偏移量为5dip
        seekBarHeight = DisplayUtil.dip2px(context,20);//默认seekBar高度为2dip
        labelTextSize = DisplayUtil.sp2px(context,12);//默认labelTextSize为12sp
        valueTextSize = labelTextSize;//默认valueTextSize = labelTextSize
        labelOffsets = DisplayUtil.dip2px(context,3);
        mPaint = new Paint();
        mPaint.setStyle(Paint.Style.STROKE);
        mPaint.setColor(Color.BLACK);//默认黑色
        mPaint.setTextSize(labelTextSize);
        mPaint.setTextAlign(Paint.Align.CENTER);
        mPaint.setAntiAlias(true);
        mBound = new Rect();

        seekBarPaint = new Paint();
        seekBarPaint.setStrokeWidth(1);
        seekBarPaint.setStyle(Paint.Style.FILL_AND_STROKE);
        seekBarPaint.setColor(seekBarBgColor);//seekBar背景颜色，默认灰色
        seekBarPaint.setAntiAlias(true);
    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec)
    {
        int widthMode = MeasureSpec.getMode(widthMeasureSpec);
        int widthSize = MeasureSpec.getSize(widthMeasureSpec);
        int heightMode = MeasureSpec.getMode(heightMeasureSpec);
        int heightSize = MeasureSpec.getSize(heightMeasureSpec);
        if (widthMode == MeasureSpec.EXACTLY)
        {
            width = widthSize;
        }
        mPaint.setTextSize(labelTextSize);
        String mTitle = "标签";
        mPaint.getTextBounds(mTitle, 0, mTitle.length(), mBound);
        float textHeight = mBound.height();
        int desiredHeight = (int) (getPaddingTop() + textHeight + getPaddingBottom())+(int)(offsets*2);
        if (heightMode == MeasureSpec.EXACTLY)
        {
            height = heightSize;
            seekBarHeight = height - desiredHeight;
        }
        else
        {
            int desired = (int) (getPaddingTop() + textHeight + getPaddingBottom())+(int)(offsets*2)+seekBarHeight;
            height = desired;
        }
        seekBarWidth = width-getPaddingRight()-getPaddingLeft();
        setMeasuredDimension(width, height);
        calculateData();
    }

    @Override
    protected void onDraw(Canvas canvas)
    {
        super.onDraw(canvas);
        canvas.drawColor(bgColor);//绘制整体view背景
        drawSeekBarBg(canvas);
        if(leftProgress==0 && rightProgress==0)
        {
            mPaint.setColor(defaultSeekBarBgTextColor);
            Paint.FontMetrics fontMetrics = mPaint.getFontMetrics();
            float textX = getPaddingLeft() + seekBarWidth/2f;
            float textY = (seekBarHeight - fontMetrics.bottom + fontMetrics.top) / 2f - fontMetrics.top+offsets;
            canvas.drawText(emptyText,textX,textY,mPaint);
            return;
        }
        drawLeftSeekBar(canvas);
        drawRightSeekBar(canvas);
    }

    /**
     * 计算数据
     */
    private void calculateData()
    {
        float leftValue = 0;
        float rightValue = 0;
        if(leftSeekBarData != null)
        {
            leftValue = leftSeekBarData.getDataValue();
        }
        if(rightSeekBarData != null)
        {
            rightValue = rightSeekBarData.getDataValue();
        }
        if(leftValue > 0 || rightValue > 0)
        {
            if(leftValue > rightValue)
            {
                leftProgress = seekBarWidth/2f;
                rightProgress = ((seekBarWidth/2f)/leftValue)*rightValue;
            }
            else
            {
                rightProgress = seekBarWidth/2f;
                leftProgress = ((seekBarWidth/2f)/rightValue)*leftValue;
            }
        }
    }

    /**
     * 绘制右边的seekBar
     * @param canvas
     */
    private void drawRightSeekBar(Canvas canvas)
    {
        seekBarPaint.setColor(rightSeekBarColor);
        float left = getPaddingLeft()+seekBarWidth/2f;
        float top = offsets;
        float right = left+currentRightPro;
        float bottom = offsets+seekBarHeight;
        canvas.drawRect(left,top,right,bottom,seekBarPaint);

        //绘制文本
        mPaint.setColor(rightSeekBarData.getDataValueColor());
        mPaint.setTextSize(valueTextSize);
        String rightSeekBarValue = rightSeekBarData.getDataValue()+"";
        Paint.FontMetrics fontMetrics = mPaint.getFontMetrics();

        float rightTextWidth = mPaint.measureText(rightSeekBarValue)+valueOffsets*2;
        float textX = right - rightTextWidth/2f;
        float textY = (seekBarHeight - fontMetrics.bottom + fontMetrics.top) / 2f - fontMetrics.top+top;
        if(rightTextWidth > currentRightPro)//如果文字大小大于进度，则绘制进度外
        {
            textX = right + rightTextWidth/2f;
            mPaint.setColor(defaultSeekBarBgTextColor);
        }
        canvas.drawText(rightSeekBarValue,textX,textY,mPaint);

        String labelText = rightSeekBarData.getLabelValue();
        mPaint.getTextBounds(labelText, 0, labelText.length(), mBound);
        mPaint.setColor(rightSeekBarData.getLabelColor());
        mPaint.setTextSize(labelTextSize);
        float textHeight = mBound.height();
        float labelTextWidth = mPaint.measureText(labelText);
        float pointX = right;
        float pointY = (textHeight - fontMetrics.bottom + fontMetrics.top) / 2f - fontMetrics.top+bottom+offsets;
        if((pointX+labelTextWidth/2f) > (width-labelOffsets))
        {
            pointX = width-labelTextWidth/2f-labelOffsets;
        }
        canvas.drawText(labelText,pointX,pointY,mPaint);
    }

    /**
     * 绘制左边的seekBar
     * @param canvas
     */
    private void drawLeftSeekBar(Canvas canvas)
    {
        seekBarPaint.setColor(leftSeekBarColor);
        float top = offsets;
        float right = seekBarWidth/2f+getPaddingLeft();
        float left = right - currentLeftPro;
        float bottom = offsets+seekBarHeight;
        canvas.drawRect(left,top,right,bottom,seekBarPaint);
        //绘制文本
        mPaint.setColor(leftSeekBarData.getDataValueColor());
        mPaint.setTextSize(valueTextSize);
        String leftSeekBarValue = leftSeekBarData.getDataValue()+"";
        Paint.FontMetrics fontMetrics = mPaint.getFontMetrics();

        float leftTextWidth = mPaint.measureText(leftSeekBarValue)+valueOffsets*2;
        float textX = left + leftTextWidth/2f;
        float textY = (seekBarHeight - fontMetrics.bottom + fontMetrics.top) / 2f - fontMetrics.top+top;
        if(leftTextWidth > currentLeftPro)//如果文字大小大于进度，则绘制进度外
        {
            textX = left - leftTextWidth/2f;
            mPaint.setColor(defaultSeekBarBgTextColor);
        }
        canvas.drawText(leftSeekBarValue,textX,textY,mPaint);

        String labelText = leftSeekBarData.getLabelValue();
        mPaint.getTextBounds(labelText, 0, labelText.length(), mBound);
        float textHeight = mBound.height();
        mPaint.setColor(leftSeekBarData.getLabelColor());
        mPaint.setTextSize(labelTextSize);
        float labelTextWidth = mPaint.measureText(labelText);
        float pointX = left;
        float pointY = (textHeight - fontMetrics.bottom + fontMetrics.top) / 2f - fontMetrics.top+bottom+offsets;
        if ((pointX-labelTextWidth/2f)<labelOffsets)
        {
            pointX = labelTextWidth/2f+labelOffsets;
        }
        canvas.drawText(labelText,pointX,pointY,mPaint);
    }

    /**
     * 绘制seekBar背景
     * @param canvas
     */
    private void drawSeekBarBg(Canvas canvas)
    {
        seekBarPaint.setColor(seekBarBgColor);
        float left = getPaddingLeft();
        float top = offsets;
        float right = width-getPaddingRight();
        float bottom = offsets+seekBarHeight;
        canvas.drawRect(left,top,right,bottom,seekBarPaint);
    }

    public int getSeekBarBgColor()
    {
        return seekBarBgColor;
    }

    public void setSeekBarBgColor(int seekBarBgColor)
    {
        this.seekBarBgColor = seekBarBgColor;
    }

    public int getBgColor()
    {
        return bgColor;
    }

    public void setBgColor(int bgColor)
    {
        this.bgColor = bgColor;
    }

    public void setLeftSeekBarData(SeekBarData leftSeekBarData) {
        this.leftSeekBarData = leftSeekBarData;
    }

    public void setRightSeekBarData(SeekBarData rightSeekBarData) {
        this.rightSeekBarData = rightSeekBarData;
    }

    public int getDefaultSeekBarBgTextColor() {
        return defaultSeekBarBgTextColor;
    }

    public void setDefaultSeekBarBgTextColor(int defaultSeekBarBgTextColor) {
        this.defaultSeekBarBgTextColor = defaultSeekBarBgTextColor;
    }

    public float getOffsets() {
        return offsets;
    }

    public void setOffsets(float offsets) {
        this.offsets = offsets;
    }

    public float getValueOffsets() {
        return valueOffsets;
    }

    public void setValueOffsets(float valueOffsets) {
        this.valueOffsets = valueOffsets;
    }

    public int getValueTextSize() {
        return valueTextSize;
    }

    public void setValueTextSize(int valueTextSize) {
        this.valueTextSize = valueTextSize;
    }

    public int getLabelTextSize() {
        return labelTextSize;
    }

    public void setLabelTextSize(int labelTextSize) {
        this.labelTextSize = labelTextSize;
    }

    public int getLeftSeekBarColor() {
        return leftSeekBarColor;
    }

    public void setLeftSeekBarColor(int leftSeekBarColor) {
        this.leftSeekBarColor = leftSeekBarColor;
    }

    public int getRightSeekBarColor() {
        return rightSeekBarColor;
    }

    public void setRightSeekBarColor(int rightSeekBarColor) {
        this.rightSeekBarColor = rightSeekBarColor;
    }

    public String getEmptyText() {
        return emptyText;
    }

    public void setEmptyText(String emptyText) {
        this.emptyText = emptyText;
    }

    public long getDurationMillis() {
        return durationMillis;
    }

    public void setDurationMillis(long durationMillis) {
        this.durationMillis = durationMillis;
    }

    public static class SeekBarData
    {
        /**
         * 数值
         */
        private float dataValue;
        /**
         * 标签
         */
        private String labelValue;
        /**
         * 标签颜色
         */
        private int labelColor;
        /**
         * 数值颜色
         */
        private int dataValueColor;

        public int getLabelColor()
        {
            return labelColor;
        }

        public void setLabelColor(int labelColor)
        {
            this.labelColor = labelColor;
        }

        public int getDataValueColor()
        {
            return dataValueColor;
        }

        public void setDataValueColor(int dataValueColor)
        {
            this.dataValueColor = dataValueColor;
        }

        public float getDataValue()
        {
            return dataValue;
        }

        public void setDataValue(float dataValue)
        {
            this.dataValue = dataValue;
        }

        public String getLabelValue()
        {
            return labelValue;
        }

        public void setLabelValue(String labelValue)
        {
            this.labelValue = labelValue;
        }

    }

    /**
     * 设置进度
     * 同步，允许多线程访问
     */
    public void refreshProgress()
    {
        if (currentLeftPro < 0 || currentLeftPro > leftProgress || currentRightPro < 0 || currentRightPro > rightProgress)
        {
            throw new IllegalArgumentException("数值异常");
        }
        postInvalidate(); // 可以直接在子线程中调用，而invalidate()必须在主线程（UI线程）中调用
    }

    private void startAnimator()
    {
        ValueAnimator leftValueAnimator = ValueAnimator.ofFloat(0f,1.0f);
        leftValueAnimator.setInterpolator(new AccelerateDecelerateInterpolator());
        leftValueAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
            @Override
            public void onAnimationUpdate(ValueAnimator valueAnimator) {
                currentLeftPro = (float) valueAnimator.getAnimatedValue()*leftProgress;
            }
        });
        ValueAnimator rightValueAnimator = ValueAnimator.ofFloat(0f,1.0f);
        rightValueAnimator.setInterpolator(new AccelerateDecelerateInterpolator());
        rightValueAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
            @Override
            public void onAnimationUpdate(ValueAnimator valueAnimator) {
                currentRightPro = (float) valueAnimator.getAnimatedValue()*rightProgress;
                refreshProgress();
            }
        });
        AnimatorSet animatorSet = new AnimatorSet();
        animatorSet.playTogether(leftValueAnimator,rightValueAnimator);
        animatorSet.setDuration(durationMillis);
        animatorSet.start();
    }

    public void refreshView()
    {
        currentLeftPro = 0;
        currentRightPro = 0;
        calculateData();
        startAnimator();
    }
}
